package com.piesat.quake.business.device.mqtt.factory;

import com.piesat.quake.business.device.mqtt.anno.PipelineNode;
import com.piesat.quake.business.device.mqtt.pipeline.DataPipeline;
import com.piesat.quake.business.device.mqtt.pipeline.Pipeline;

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 流水线上下文
 *
 * @author Gersy
 * @date 2023/3/8
 * @since 1.0
 */
@Component
public class PipelineContext {
    private final PipelineFactory<Class<?>> annotationPipelineFactory = new AnnotationPipelineFactory();
    private final ConcurrentHashMap<String, DataPipeline> pipelineMap = new ConcurrentHashMap<>();

    public static void main(String[] args) {
        PipelineContext pipelineContext = new PipelineContext();
        pipelineContext.loadAnnotationPipeline(new String[]{"com.piesat.quake.business.device.model"});
    }

    public PipelineFactory getAnnotationPipelineFactory() {
        return annotationPipelineFactory;
    }

    public void loadAnnotationPipeline(String[] basePackages) {
        PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
        for (String basePackage : basePackages) {
            String packageName = basePackage.replace(".", "/");
            String locationPattern = "classpath:" + packageName + "/**";
            try {
                Resource[] resources = pathMatchingResourcePatternResolver.getResources(locationPattern);
                for (Resource resource : resources) {
                    String url = resource.getURL().getPath();
                    String className = url.substring(url.indexOf(packageName));
                    try {
                        String replace = className.replace("/", ".").replace(".class", "");
                        if(replace.endsWith(".")){
                            continue;
                        }
                        Class<?> aClass = Class.forName(replace);
                        PipelineNode annotation = aClass.getAnnotation(PipelineNode.class);
                        if (annotation != null) {
                            Pipeline pipeline = annotationPipelineFactory.create(aClass);
                            String simpleName = aClass.getSimpleName();
                            simpleName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);
                            pipelineMap.put(simpleName, pipeline);
                        }
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public DataPipeline getPipeline(Class<?> clazz) {
        String name = clazz.getSimpleName();
        name = name.substring(0, 1).toLowerCase() + name.substring(1);
        return pipelineMap.get(name);
    }

    public DataPipeline getPipeline(String name) {
        return pipelineMap.get(name);
    }

    public void register(String name, DataPipeline pipeline) {
        if (pipelineMap.get(name) != null) {
            throw new IllegalArgumentException("名字已经被注册:" + name);
        }
        pipelineMap.put(name, pipeline);
    }
}
